﻿#include "GAF_ZoomAction.h"

namespace GAF
{
	ZoomAction::ZoomAction()
	{
		m_dBigZoom = 0.0f;
		m_dSmallZoom = 0.0f;
		m_dCurZoom = 0.0f;
		m_dStepZoom = 0.0f;
		m_nWay = 0;

		m_dBigZoomX = 0.0f;
		m_dSmallZoomX = 0.0f;
		m_dCurZoomX = 0.0f;
		m_dStepZoomX = 0.0f;
		m_nWayX = 0;

		m_dBigZoomY = 0.0f;
		m_dSmallZoomY = 0.0f;
		m_dCurZoomY = 0.0f;
		m_dStepZoomY = 0.0f;
		m_nWayY = 0;

		m_nTimes = 0;
	}

	ZoomAction::~ZoomAction()
	{
	}

	void ZoomAction::SetIntent(ActionIntent* pIntent)
	{
		GAF_CHECK(pIntent != NULL);

		ZoomIntent* _pZoomIntent = (ZoomIntent*)pIntent;

// 		m_Intent.Reset();
		_MEMCPY(&m_Intent, _pZoomIntent, sizeof(ZoomIntent));
		m_Intent.CopyControl(pIntent);
// 		m_Intent.dStartZoom = _pZoomIntent->dStartZoom;
// 		m_Intent.dEndZoom = _pZoomIntent->dEndZoom;
// 		m_Intent.dStartZoomX = _pZoomIntent->dStartZoomX;
// 		m_Intent.dEndZoomX = _pZoomIntent->dEndZoomX;
// 		m_Intent.dStartZoomY = _pZoomIntent->dStartZoomY;
// 		m_Intent.dEndZoomY = _pZoomIntent->dEndZoomY;
// 		m_Intent.nMode = _pZoomIntent->nMode;
// 		m_Intent.ttUseTime = _pZoomIntent->ttUseTime;
// 		m_Intent.nTimes = _pZoomIntent->nTimes;

		m_dBigZoom = GAF_MAX_NUM(m_Intent.dStartZoom, m_Intent.dEndZoom);
		m_dSmallZoom = GAF_MIN_NUM(m_Intent.dStartZoom, m_Intent.dEndZoom);
		m_dCurZoom = m_Intent.dStartZoom;
		m_dStepZoom = GAF_ABS_NUM(m_Intent.dStartZoom - m_Intent.dEndZoom) / m_Intent.ttRun;
		m_nWay = (m_Intent.dStartZoom >= m_Intent.dEndZoom) ? -1 : 1;

		m_dBigZoomX = GAF_MAX_NUM(m_Intent.dStartZoomX, m_Intent.dEndZoomX);
		m_dSmallZoomX = GAF_MIN_NUM(m_Intent.dStartZoomX, m_Intent.dEndZoomX);
		m_dCurZoomX = m_Intent.dStartZoomX;
		m_dStepZoomX = GAF_ABS_NUM(m_Intent.dStartZoomX - m_Intent.dEndZoomX) / m_Intent.ttRun;
		m_nWayX = (m_Intent.dStartZoomX >= m_Intent.dEndZoomX) ? -1 : 1;

		m_dBigZoomY = GAF_MAX_NUM(m_Intent.dStartZoomY, m_Intent.dEndZoomY);
		m_dSmallZoomY = GAF_MIN_NUM(m_Intent.dStartZoomY, m_Intent.dEndZoomY);
		m_dCurZoomY = m_Intent.dStartZoomY;
		m_dStepZoomY = GAF_ABS_NUM(m_Intent.dStartZoomY - m_Intent.dEndZoomY) / m_Intent.ttRun;
		m_nWayY = (m_Intent.dStartZoomY >= m_Intent.dEndZoomY) ? -1 : 1;
	}

	void ZoomAction::ZoomTo(double dTargetZoom)
	{
		ZoomIntent _intent;
		_intent.dStartZoom = GetHostGraphics()->GetZoom();
		_intent.dEndZoom = dTargetZoom;
		_intent.amMode = ACTION_AGAIN;
		_intent.ttRun = (int)GAF_ABS_NUM(_intent.dStartZoom - _intent.dEndZoom) * 20;
		_intent.nTimes = 1;

		SetIntent(&_intent);
		Play();
	}

	bool ZoomAction::OnPlay(Bundle* pParam)
	{
		bool _isPlay = false;

		if(m_Intent.dStartZoom != m_Intent.dEndZoom)
		{
			_isPlay = true;
			GetHostGraphics()->SetZoom(m_dCurZoom);
		}

		if(m_Intent.dStartZoomX != m_Intent.dEndZoomX)
		{
			_isPlay = true;
			GetHostGraphics()->SetZoomX(m_dCurZoomX);
		}

		if(m_Intent.dStartZoomY != m_Intent.dEndZoomY)
		{
			_isPlay = true;
			GetHostGraphics()->SetZoomY(m_dCurZoomY);
		}

		m_nTimes = 0;

		return _isPlay;
	}

	bool ZoomAction::OnUpdate(TimeTicks ttUsed)
	{
		double _dSetZoom = 0;
		int nAddTimes = 0;
		
		if(m_Intent.dStartZoom != m_Intent.dEndZoom)
		{
			nAddTimes += UpdateZoom(ttUsed, m_Intent.dStartZoom, m_Intent.dEndZoom, m_dBigZoom, m_dSmallZoom,
				m_dCurZoom, m_dStepZoom, m_nWay, _dSetZoom);

			GetHostGraphics()->SetZoom(_dSetZoom);
			m_dCurZoom = _dSetZoom;
		}

		if(m_Intent.dStartZoomX != m_Intent.dEndZoomX)
		{
			nAddTimes += UpdateZoom(ttUsed, m_Intent.dStartZoomX, m_Intent.dEndZoomX, m_dBigZoomX, m_dSmallZoomX,
				m_dCurZoomX, m_dStepZoomX, m_nWayX, _dSetZoom);

			GetHostGraphics()->SetZoomX(_dSetZoom);
			m_dCurZoomX = _dSetZoom;
		}

		if(m_Intent.dStartZoomY != m_Intent.dEndZoomY)
		{
			nAddTimes += UpdateZoom(ttUsed, m_Intent.dStartZoomY, m_Intent.dEndZoomY, m_dBigZoomY, m_dSmallZoomY,
				m_dCurZoomY, m_dStepZoomY, m_nWayY, _dSetZoom);

			GetHostGraphics()->SetZoomY(_dSetZoom);
			m_dCurZoomY = _dSetZoom;
		}

		if(nAddTimes > 0)
		{
			if(m_Intent.amMode == ACTION_AGAIN)
			{
				if(++m_nTimes >= m_Intent.nTimes)
					return false;

			}
			else if(m_Intent.amMode == ACTION_RETURN)
			{
				if(++m_nTimes >= (m_Intent.nTimes << 1))
					return false;
			}
		}

		return true;
	}

	bool ZoomAction::OnStop()
	{
		if(m_Intent.amMode == ACTION_AGAIN)
		{
			if(m_Intent.dStartZoom != m_Intent.dEndZoom)
				GetHostGraphics()->SetZoom(m_Intent.dEndZoom);

			if(m_Intent.dStartZoomX != m_Intent.dEndZoomX)
				GetHostGraphics()->SetZoom(m_Intent.dEndZoomX);

			if(m_Intent.dStartZoomY != m_Intent.dEndZoomY)
				GetHostGraphics()->SetZoom(m_Intent.dEndZoomY);
		}
		else if(m_Intent.amMode == ACTION_RETURN)
		{
			if(m_Intent.dStartZoom != m_Intent.dEndZoom)
				GetHostGraphics()->SetZoom(m_Intent.dStartZoom);

			if(m_Intent.dStartZoomX != m_Intent.dEndZoomX)
				GetHostGraphics()->SetZoom(m_Intent.dStartZoomX);

			if(m_Intent.dStartZoomY != m_Intent.dEndZoomY)
				GetHostGraphics()->SetZoom(m_Intent.dStartZoomY);
		}

		return true;
	}

	int ZoomAction::UpdateZoom(TimeTicks ttUsed,
		double dStart, double dEnd,
		double dBig, double dSmall,
		double dCur, double dStep,
		int& nWay, double& dSet)
	{
		int _nAddTimes = 0;

		// 应设置的值
		dSet = dCur + nWay * (ttUsed * dStep);

		if(m_Intent.amMode == ACTION_AGAIN)
		{
			if(
				// 放大判断
				(nWay > 0 && dSet > dEnd) || 
				// 缩小判断
				(nWay < 0 && dSet < dEnd))
			{
				_nAddTimes = 1;
				dSet = dStart;
			}
		}
		else if(m_Intent.amMode == ACTION_RETURN)
		{
			// 放大判断
			if(nWay > 0 && dSet > dBig)
			{
				_nAddTimes = 1;
				dSet = dBig;
				nWay = -1;
			}
			// 缩小判断
			else if(m_nWay < 0 && dSet < m_dSmallZoom)
			{
				_nAddTimes = 1;
				dSet = dSmall;
				nWay = 1;
			}
		}

		return _nAddTimes;
	}
}
